home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / comobj.lisp / part11 < prev    next >
Encoding:
Text File  |  1987-08-02  |  39.3 KB  |  1,574 lines

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i085:  Common Objects, Common Loops, Common Lisp, Part11/13
  5. Message-ID: <756@uunet.UU.NET>
  6. Date: 3 Aug 87 21:18:58 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1563
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Roy D'Souza <dsouza%hplabsc@hplabs.HP.COM>
  12. Posting-number: Volume 10, Issue 85
  13. Archive-name: comobj.lisp/Part11
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 11 (of 13)."
  22. # Contents:  co-dtype.l
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'co-dtype.l' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'co-dtype.l'\"
  26. else
  27. echo shar: Extracting \"'co-dtype.l'\" \(36944 characters\)
  28. sed "s/^X//" >'co-dtype.l' <<'END_OF_FILE'
  29. X
  30. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  31. X;
  32. X; File:         co-dtype.l
  33. X; RCS:          $Revision: 1.1 $
  34. X; SCCS:         %A% %G% %U%
  35. X; Description:  CommonObjects types.
  36. X; Author:       James Kempf
  37. X; Created:      March 10, 1987
  38. X; Modified:     12-Mar-87 09:58:43 (James Kempf)
  39. X; Language:     Lisp
  40. X; Package:      COMMON-OBJECTS
  41. X; Status:       Distribution
  42. X;
  43. X; (c) Copyright 1987, HP Labs, all rights reserved.
  44. X;
  45. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  46. X;
  47. X; Copyright (c) 1987 Hewlett-Packard Corporation. All rights reserved.
  48. X;
  49. X; Use and copying of this software and preparation of derivative works based
  50. X; upon this software are permitted.  Any distribution of this software or
  51. X; derivative works must comply with all applicable United States export
  52. X; control laws.
  53. X; 
  54. X; This software is made available AS IS, and Hewlett-Packard Corporation makes
  55. X; no warranty about the software, its performance or its conformity to any
  56. X; specification.
  57. X;
  58. X; Suggestions, comments and requests for improvement may be mailed to
  59. X; aiws@hplabs.HP.COM
  60. X
  61. X;;;-*-Mode:LISP; Package:(CO (PCL LISP)); Base:10; Syntax: Common-lisp-*-
  62. X;;;
  63. X;;; *************************************************************************
  64. X;;; Copyright (c) 1985 Xerox Corporation.  All rights reserved.
  65. X;;;
  66. X;;; Use and copying of this software and preparation of derivative works
  67. X;;; based upon this software are permitted.  Any distribution of this
  68. X;;; software or derivative works must comply with all applicable United
  69. X;;; States export control laws.
  70. X;;; 
  71. X;;; This software is made available AS IS, and Xerox Corporation makes no
  72. X;;; warranty about the software, its performance or its conformity to any
  73. X;;; specification.
  74. X;;; 
  75. X;;; Any person obtaining a copy of this software is requested to send their
  76. X;;; name and post office or electronic mail address to:
  77. X;;;   CommonLoops Coordinator
  78. X;;;   Xerox Artifical Intelligence Systems
  79. X;;;   2400 Hanover St.
  80. X;;;   Palo Alto, CA 94303
  81. X;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa)
  82. X;;;
  83. X;;; Suggestions, comments and requests for improvements are also welcome.
  84. X;;; *************************************************************************
  85. X
  86. X(in-package 'common-objects :nicknames '(co) :use '(lisp pcl walker))
  87. X
  88. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  89. X;  Define-Type
  90. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  91. X
  92. X;;define-type-Define a CommonObjects type
  93. X
  94. X(defmacro define-type (&rest body)
  95. X
  96. X     (internal-define-type body)
  97. X
  98. X) ;end define-type
  99. X
  100. X;;internal-define-type-Parse a CommonObjects type definition and
  101. X;;  generate code for creating the type.
  102. X
  103. X(defun internal-define-type (body)
  104. X
  105. X   (let
  106. X     (
  107. X       (doc-string NIL) ;;documentation string, if any
  108. X       (name NIL)    ;;type name
  109. X       (parents NIL)    ;;list of parents
  110. X       (slots   NIL)    ;;list of instance variables
  111. X       (options NIL)    ;;options list
  112. X       (phonytiv NIL)    ;;phony type info vector. Used to
  113. X                        ;;  hold type definition during
  114. X                        ;;  parsing.
  115. X       (assignments NIL);;variable initializations
  116. X       (settables NIL)    ;;settable method names
  117. X       (gettables NIL)    ;;gettable method names
  118. X       (inherited NIL)    ;;inherited methods w. parents
  119. X       (keywords NIL)   ;;keywords for initialization
  120. X       (init-key-check  ;;T if a check should occur
  121. X        NIL
  122. X       )
  123. X       (dont-define NIL)  ;;methods to not define
  124. X     )
  125. X
  126. X  
  127. X     ;;Get name and options
  128. X
  129. X     (multiple-value-setq
  130. X      (name doc-string options)
  131. X        (co-parse-define-type-call (cons 'define-type body) 
  132. X                   name doc-string options
  133. X        )
  134. X     )
  135. X
  136. X     ;;Make a phony type info for use with options parsing code
  137. X
  138. X     (setf phonytiv (build-phony-type-info name))     
  139. X
  140. X     ;;Get variable names, assignments, and other options
  141. X
  142. X     (multiple-value-setq
  143. X      (slots assignments options)
  144. X      (co-process-var-options phonytiv options slots assignments)
  145. X     )
  146. X
  147. X     ;;Fill in phony type info with option information
  148. X
  149. X     (co-parse-options phonytiv slots options)
  150. X
  151. X     (setf parents (svref phonytiv $PARENT-TYPES-SLOT))
  152. X
  153. X     (setf gettables (svref phonytiv $GETTABLE-VARIABLES-SLOT))
  154. X     (setf settables (svref phonytiv $SETTABLE-VARIABLES-SLOT))
  155. X     (setf inherited (svref phonytiv $METHODS-TO-INHERIT-SLOT))
  156. X     (setf init-key-check 
  157. X    (not (svref phonytiv $NO-INIT-KEYWORD-CHECK-SLOT))
  158. X     )
  159. X     (setf dont-define 
  160. X       (svref phonytiv $METHODS-TO-NOT-DEFINE-SLOT)
  161. X     )
  162. X
  163. X     ;;Make keywords out of initiable variables and merge with
  164. X     ;;  keywords
  165. X
  166. X     (setf keywords 
  167. X           (append
  168. X         (svref phonytiv  $INIT-KEYWORDS-SLOT)
  169. X             (mapcar 
  170. X               #'(lambda (x) 
  171. X                 (intern (symbol-name x) (find-package 'keyword))
  172. X               )
  173. X               (svref phonytiv $INITABLE-VARIABLES-SLOT)
  174. X             )
  175. X           )
  176. X
  177. X    ) ;setf
  178. X
  179. X    ;;All compile-time checking must be done BEFORE the compile-time
  180. X    ;;  class definition is done, so that errors don't leave
  181. X    ;;  around a bogus class.
  182. X
  183. X    ;;Merge duplicate method names and check for inheritance
  184. X    ;;  funny business
  185. X
  186. X    (merge-duplicates name gettables settables inherited dont-define)
  187. X
  188. X     ;;Fully define the class at compile-time, so that 
  189. X     ;;  method definition works. Note that this means that
  190. X     ;;  any pre-existing definition will be clobbered.
  191. X     ;;  Compile time definition is needed for
  192. X     ;;  any other methods which are defined in the same
  193. X     ;;  file as a type definition. This is necessary because
  194. X     ;;  the metaobject protocol doesn't distinguish between
  195. X     ;;  a partially defined type and a fully defined one.
  196. X     ;;  Compile-time definition is no longer needed for
  197. X     ;;  definition of inherited, universal, and get/set
  198. X     ;;  methods, since the metaobject protocol is gone
  199. X     ;;  around for these, except for the :INITIALIZE-VARIABLES
  200. X     ;;  method, which is still generated in full.
  201. X
  202. X     (fully-define-type name slots parents keywords init-key-check)
  203. X
  204. X     ;;Generate code for the class definition. This code
  205. X     ;;  defines the class at load time and the universal
  206. X     ;;  methods.
  207. X
  208. X    `(progn
  209. X
  210. X       ;;This only needs to get done at load time, since
  211. X       ;;  class definition at compile time (to take
  212. X       ;;  care of :INITIALIZE-VARIABLES method generation
  213. X       ;;  and others in the file) is done during the macro
  214. X       ;;  expansion. Also, it need not get done if the
  215. X       ;;  definition is being evaluated, since the macro
  216. X       ;;  has already done in.
  217. X
  218. X       (eval-when (load)
  219. X     (fully-define-type ',name 
  220. X                    ',slots 
  221. X                ',parents
  222. X                ',keywords
  223. X                ',init-key-check
  224. X     )
  225. X       )
  226. X
  227. X        ;;Define the initialization, get/set, and inherited methods.
  228. X
  229. X        ;;Variable initialization is handled by generating an
  230. X        ;;  initialization method. The :INITIALIZE-VARIABLES method 
  231. X        ;;  is the only universal one  generated on a type by type basis.
  232. X        ;;  Since the user can insert anything into the initialization
  233. X        ;;  forms, the code must go through the full processing
  234. X        ;;  for method definition, including code walking of
  235. X        ;;  WITH-SLOTS. This requires that the PCL class be
  236. X        ;;  defined at compile time.
  237. X
  238. X        ,(if (not (member ':initialize-variables dont-define))
  239. X          (build-init-vars-method
  240. X            name
  241. X            (svref phonytiv $INITABLE-VARIABLES-SLOT)
  242. X        assignments
  243. X          )
  244. X        )
  245. X
  246. X    ;;Universal methods are no longer defined on a per type
  247. X        ;;  basis, but rather default methods are defined
  248. X        ;;  for all CommonObjects types. The user can define
  249. X    ;;  their own methods which override the default ones,
  250. X    ;;  but the defaults can't be undefined or renamed.
  251. X    ;;  Using defaults saves time during type definition.
  252. X
  253. X        ;;Inherited methods  must be defined
  254. X        ;;  at compile time, otherwise the CLASS-DIRECT-METHODS
  255. X        ;;  call in METHOD-ALIST won't find the gettable and
  256. X        ;;  settable methods during compilation. This is
  257. X        ;;  also true for gettable and settable methods.
  258. X        ;;  Note, however, that other methods defined in
  259. X        ;;  the same file will NOT get inherited, because
  260. X        ;;  they are not fully defined at compile time.
  261. X        ;;  This means that users should avoid defining
  262. X        ;;  parent and child types in the same file.
  263. X        ;;  In particular, the ADD-METHOD call generated
  264. X        ;;  by the PCL method generation code only gets
  265. X        ;;  done at load time, and hence seperately defined
  266. X        ;;  methods are only returned by CLASS-DIRECT-METHODS
  267. X        ;;  after loading. The code below  will cause the 
  268. X        ;;  (EVAL-WHEN (LOAD) ...) top level forms returned 
  269. X        ;;  by the PCL method code generation to be overridden.
  270. X
  271. X
  272. X          ;;Inherited methods
  273. X
  274. X          ,@(build-inherited-methods name inherited dont-define parents slots)
  275. X
  276. X          ;;Gettables and settables
  277. X
  278. X      ,@(build-gs-methods name gettables settables dont-define parents slots)
  279. X
  280. X          ',name
  281. X
  282. X       ) ;progn
  283. X
  284. X
  285. X  ) ;end let
  286. X) ;end internal-define-type
  287. X
  288. X;;fully-define-type-Fully define the CommonObjects type 
  289. X
  290. X(defun fully-define-type (name slots parents keywords init-key-check)
  291. X
  292. X  (let
  293. X    (
  294. X      (classprot (class-prototype (class-named 'common-objects-class)))
  295. X    )
  296. X
  297. X    ;;Check for redefinition incompatibility, if any.
  298. X
  299. X    (check-for-redefinition-incompatibility name parents slots)
  300. X
  301. X    (add-named-class classprot
  302. X             name
  303. X             parents
  304. X             slots
  305. X             NIL
  306. X    )
  307. X
  308. X
  309. X    ;;Now set the slots for the initialization keywords and
  310. X    ;;  the check flag
  311. X
  312. X    (setf classprot (class-named name))
  313. X    (setf (class-init-keywords classprot) keywords)      
  314. X    (setf (class-init-keywords-check classprot) init-key-check)
  315. X
  316. X  ) ;let
  317. X
  318. X) ;end fully-define-type
  319. X
  320. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  321. X;  Auxillary Type Definition Functions
  322. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  323. X
  324. X;;build-phony-type-info-Make a phony type info vector, to hold the
  325. X;;  information while the DEFINE-TYPE call is being parsed.
  326. X
  327. X(defun build-phony-type-info (name)
  328. X
  329. X;;Check if the name is OK first
  330. X
  331. X  (unless (co-legal-type-or-method-name name)
  332. X    (co-deftype-error "legal type names must be symbols and NOT the symbol NIL."
  333. X      name
  334. X    )
  335. X  )
  336. X
  337. X  ;;Set the name and origin slots and return
  338. X
  339. X  (let
  340. X    (
  341. X      (phonytiv 
  342. X    (make-array 
  343. X      $INFO-NUMBER-OF-SLOTS
  344. X      :initial-element NIL
  345. X        )
  346. X      )
  347. X    )
  348. X
  349. X    (setf (svref phonytiv $TYPE-NAME-SLOT) name)
  350. X
  351. X    phonytiv
  352. X
  353. X    ;;Note that we don't check for predefined type info's here
  354. X    ;;  because that should (eventually!) be handled by
  355. X    ;;  the CommonLoops kernel
  356. X
  357. X  ) ;end let
  358. X
  359. X) ;end build-phony-type-info
  360. X
  361. X;;check-for-redefinition-incompatibility-Check to see if redefining
  362. X;;  will cause an incompatible change
  363. X
  364. X(defun check-for-redefinition-incompatibility (name newparents newslots)
  365. X
  366. X  (let*
  367. X    (
  368. X      (oldclass (class-named name T))
  369. X    )
  370. X
  371. X
  372. X    ;;If no class object, then this is new      
  373. X
  374. X    (when oldclass
  375. X
  376. X      ;;Check instance variable incompatibility
  377. X
  378. X      (if (not (slots-compatible-p newslots (class-user-visible-slots oldclass)))
  379. X        (co-deftype-error
  380. X        "please rename, since changing instance variables is incompatible.~%"
  381. X        name
  382. X        )
  383. X      )
  384. X
  385. X      ;;Check for parent incompatibility
  386. X
  387. X      (if (not 
  388. X        (slots-compatible-p 
  389. X          newparents 
  390. X          (class-local-super-names oldclass)
  391. X            )
  392. X          )
  393. X        (co-deftype-error
  394. X        "please rename, since changing parents is incompatible.~%"
  395. X        name
  396. X        )
  397. X      )
  398. X
  399. X    ) ;when
  400. X
  401. X  ) ;let
  402. X
  403. X) ;end check-for-redefinition-incompatibility
  404. X
  405. X;;slots-compatible-p-Check if the number and ordering
  406. X;;  of the slots in the old and new lists is the same
  407. X
  408. X(defun slots-compatible-p (newslots oldslots)
  409. X
  410. X  ;;Check that number of slots is the same
  411. X
  412. X  (when (not (= (length oldslots) (length newslots)))
  413. X    (return-from slots-compatible-p NIL) 
  414. X  )
  415. X
  416. X  ;;Check slot names
  417. X    
  418. X  (do
  419. X    (
  420. X      (ns newslots (cdr ns))
  421. X      (os oldslots (cdr os))
  422. X    )
  423. X    ( (or (null ns) (null os)) )
  424. X
  425. X    (if (not (eq (car ns) (car os)))
  426. X      (return-from slots-compatible-p NIL)
  427. X    ) ;if
  428. X  ) ;do
  429. X
  430. X  T
  431. X) ;end slots-compatible-p
  432. X
  433. X;;merge-duplicates-Merge duplicates and check for conflicts
  434. X;;   in parents.
  435. X
  436. X(defun merge-duplicates (name gettables settables parents dont-define)
  437. X
  438. X  ;;Destructively modify gettables and settables
  439. X  ;;to get rid of duplicates
  440. X
  441. X  (merge-methods gettables settables)
  442. X
  443. X  ;;Check for funny business in inheritance
  444. X
  445. X  (check-for-funny-inheritance name parents)
  446. X
  447. X  ;;Check if any conflicts with parents and among parents
  448. X
  449. X  (check-for-method-conflicts name gettables parents dont-define)
  450. X
  451. X  NIL
  452. X) ;end merge-duplicates
  453. X
  454. X;;merge-methods-Put settables on gettable list
  455. X
  456. X(defun merge-methods (gettables settables)
  457. X
  458. X  (dolist (meth settables)
  459. X
  460. X    (when (not (member meth gettables :test #'equal))
  461. X      (setf (cdr (last gettables)) (list meth ) )
  462. X    )
  463. X  ) ;dolist
  464. X
  465. X) ;end merge-methods
  466. X
  467. X;;check-for-funny-inheritance-Check for attempts to inherit
  468. X;;  from yourself
  469. X
  470. X(defun check-for-funny-inheritance (name parents)
  471. X
  472. X  ;;Check me
  473. X
  474. X  (dolist (p parents)
  475. X
  476. X    ;; Check me
  477. X
  478. X    (if (eq name (class-name (car p)))
  479. X      (co-deftype-error"this type has itself as an ancestor.~%" name)
  480. X    )
  481. X
  482. X    ;;Check parent
  483. X
  484. X    (check-for-funny-inheritance name (mapcar #'list (class-local-supers (car p))))
  485. X  )
  486. X
  487. X) ;end check-for-funny-inheritance
  488. X
  489. X;;check-for-method-conflicts-Merge gettable and parent lists and
  490. X;;  check for conflicts.
  491. X
  492. X(defun check-for-method-conflicts (name gettables parents dont-define)
  493. X
  494. X  (let
  495. X    (
  496. X      (kwp (find-package 'keyword))
  497. X      (meths NIL)
  498. X    )
  499. X
  500. X    ;;Intern the gettable names in the keyword package
  501. X
  502. X    (dolist (g gettables)
  503. X      (setf meths (cons (intern (symbol-name g) kwp) meths))
  504. X    ) ;dolist
  505. X
  506. X    ;;Concatenate the parent methods onto the end
  507. X
  508. X    (dolist (p parents)
  509. X
  510. X      (setf meths 
  511. X    (concatenate 
  512. X      'list 
  513. X      meths 
  514. X      (cdr p)
  515. X    )
  516. X      )
  517. X
  518. X    ) ;dolist
  519. X
  520. X    ;;Now check for duplicates
  521. X
  522. X    (check-for-conflicts name meths dont-define)
  523. X
  524. X  ) ;let
  525. X
  526. X) ;end check-for-method-conflicts
  527. X
  528. X;;check-for-conflicts-Check if any generated methods
  529. X;;  conflict
  530. X
  531. X(defun check-for-conflicts (name list dont-define)
  532. X
  533. X    (setf list (sort list #'(lambda (x y) (string-lessp (symbol-name x) (symbol-name y)))))
  534. X
  535. X    (do*
  536. X      (
  537. X        (item (car list) (car clist))
  538. X        (clist (cdr list) (cdr clist))
  539. X      )
  540. X      ((eq clist NIL))
  541. X
  542. X      ;;Check if a method already exists and isn't on the don't define
  543. X      ;;  list
  544. X
  545. X      (if (and (equal item (car clist)) (not (member item dont-define)))
  546. X        (co-deftype-error
  547. X      "two methods ~S exist during method generation.~%~
  548. X           Please undefine one or the other.~%"
  549. X      name item
  550. X        )
  551. X      )
  552. X    ) ;do
  553. X
  554. X) ;end check-for-conflicts
  555. X
  556. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  557. X;  Top Level Method Building Functions
  558. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  559. X
  560. X;;build-inherited-methods-Build the list of inherited methods by using
  561. X;;  apply-method
  562. X
  563. X(defun build-inherited-methods (name parents dont-define parent-names slots)
  564. X
  565. X  (let
  566. X    (
  567. X      (methcode NIL)
  568. X    )
  569. X
  570. X    ;;Do all the parents
  571. X
  572. X    (dolist (p parents)
  573. X
  574. X      ;;Do this parent's list
  575. X
  576. X      (dolist (m (cdr p))
  577. X
  578. X        ;;Check first to be sure it should be defined
  579. X
  580. X        (if (not (member m dont-define))
  581. X
  582. X      (push
  583. X            (build-inherited-method 
  584. X              name 
  585. X              m 
  586. X              (class-name (car p)) 
  587. X              parent-names 
  588. X              slots
  589. X            )
  590. X            methcode
  591. X          )
  592. X
  593. X        )
  594. X
  595. X      ) ;dolist
  596. X    ) ;dolist
  597. X
  598. X    methcode
  599. X
  600. X  ) ;let
  601. X
  602. X) ;build-inherited-methods
  603. X
  604. X;;build-gs-methods-Build gettable and settable methods
  605. X
  606. X(defun build-gs-methods (typename gettables settables dont-define parents slots)
  607. X
  608. X  (let
  609. X    (
  610. X      (methcode NIL)
  611. X      (kwp (find-package 'keyword))
  612. X      (meth NIL)
  613. X    )
  614. X
  615. X    ;;First do gettables
  616. X
  617. X    (dolist (g gettables)
  618. X
  619. X      (setf meth (intern (symbol-name g) kwp))
  620. X
  621. X      ;;Check first to be sure it must be defined
  622. X
  623. X      (if (not (member meth dont-define))
  624. X
  625. X        (push  
  626. X          (build-get-method typename 
  627. X                            meth
  628. X                            g 
  629. X                            parents 
  630. X                            slots
  631. X           )
  632. X          methcode
  633. X        )
  634. X      )
  635. X
  636. X
  637. X    ) ;dolist
  638. X
  639. X    ;;Now do settables
  640. X
  641. X    (dolist (s settables)
  642. X
  643. X      (setf meth 
  644. X            (intern (concatenate 'simple-string "SET-" (symbol-name s)) kwp)
  645. X      )
  646. X
  647. X      ;;Check first to be sure it must be defined
  648. X
  649. X      (if (not (member s dont-define))
  650. X        (push
  651. X      (build-set-method 
  652. X        typename 
  653. X            meth 
  654. X        s
  655. X            parents
  656. X            slots
  657. X          )
  658. X      methcode
  659. X        )
  660. X      )
  661. X
  662. X    ) ;dolist
  663. X
  664. X    methcode
  665. X
  666. X  ) ;let
  667. X) ;end build-gs-methods  
  668. X
  669. X;;build-init-vars-method-Return code for the :INITIALIZE-VARIABLES
  670. X;;  method. Note that this must be a fully-blown CommonObjects
  671. X;;  method, because the users can put anthing they want into
  672. X;;  the initialization code, including CALL-METHOD.
  673. X
  674. X(defun build-init-vars-method
  675. X  (name initable-slots assignments)
  676. X
  677. X  (let
  678. X    (    
  679. X      (form NIL)
  680. X      (kwpak (find-package 'keyword))
  681. X      (code NIL)
  682. X    )
  683. X
  684. X
  685. X    ;;This code is stolen from DEFINE-METHOD and is
  686. X    ;;  inserted in line here so that, when it
  687. X    ;;  gets returned to the top level, PCL::EXPAND-DEFMETH-INTERNAL
  688. X    ;;  gets invoked while the DEFINE-TYPE macro is executing,
  689. X    ;;  rather than at the top level, when the macro has
  690. X    ;;  finished executing.
  691. X
  692. X    (setf code
  693. X      `(compiler-let
  694. X        (
  695. X          (*current-method-class-name* ',name)
  696. X        )   
  697. X
  698. X
  699. X        (let ((self (self-from-inner-self)))
  700. X           (declare (optimize (speed 3) (safety 0)))
  701. X
  702. X          (with*
  703. X            (
  704. X              (.inner-self. "" ,name)
  705. X            )
  706. X
  707. X            ,(if initable-slots
  708. X
  709. X              `(do*
  710. X                (
  711. X              (unprocessed-keys keylist (cddr unprocessed-keys))
  712. X              (keyword (car unprocessed-keys) (car unprocessed-keys))
  713. X              (value (cadr unprocessed-keys) (cadr unprocessed-keys))
  714. X                )
  715. X                ( (null unprocessed-keys) )
  716. X                (case keyword
  717. X                ,@(dolist (var initable-slots form)
  718. X                  (push 
  719. X                        `(
  720. X                          (,(intern (symbol-name var) kwpak) ) 
  721. X                          (setf ,var value)
  722. X                        ) 
  723. X                form
  724. X                      )
  725. X                )
  726. X                  )
  727. X              )
  728. X
  729. X           ) ;if
  730. X
  731. X            ,@assignments
  732. X
  733. X          ) ;with*
  734. X
  735. X      ) ;let
  736. X      ) ;compiler-let
  737. X    ) ;setf
  738. X
  739. X    ;;Now define as a full blown CommonObjects method, with code
  740. X    ;; walking and everything. Add in CALL-METHOD processing.
  741. X
  742. X    `(progn
  743. X
  744. X      ,(defcommon-objects-meth 
  745. X        'keyword-standin::initialize-variables
  746. X        `((.inner-self. ,name) &rest keylist)
  747. X        code
  748. X      )
  749. X
  750. X     ) ;progn
  751. X
  752. X   ) ;end let
  753. X
  754. X) ;end build-init-vars-method
  755. X
  756. X;;build-pcl-method-def-Build a PCL method definition without
  757. X;; all the overhead of code walking and method object creation
  758. X;; at compile time
  759. X
  760. X(defun build-pcl-method-def (type method func-args code)
  761. X
  762. X  (setf method
  763. X        (if (keywordp method)
  764. X            (keyword-standin method)
  765. X            method
  766. X        )
  767. X  )
  768. X
  769. X  (let*
  770. X    (
  771. X      (type-spec (list type))
  772. X      (method-function-name (pcl::make-method-name method type-spec))
  773. X    )
  774. X
  775. X    ;;The extra list is so the forms get inserted at the
  776. X    ;;  top level OK
  777. X
  778. X   `(
  779. X     (eval-when (compile load eval)
  780. X       (pcl::record-definition 
  781. X         ',method 'pcl::method ',type-spec NIL
  782. X       )
  783. X       (defun ,method-function-name ,func-args
  784. X         (declare (optimize (speed 3) (safety 0)))
  785. X    ,code
  786. X       )
  787. X     )
  788. X
  789. X     ;;Note that this must be done at compile time
  790. X     ;;  as well, since inherited methods must
  791. X     ;;  be there for other types in the file
  792. X
  793. X     (eval-when (compile load eval)
  794. X       (let
  795. X         (
  796. X           (method 
  797. X             (pcl::load-method-1
  798. X               'pcl::discriminator
  799. X               'common-objects-method
  800. X               ',method
  801. X               ',type-spec
  802. X               ',func-args
  803. X               NIL
  804. X             )
  805. X
  806. X           )
  807. X
  808. X        )
  809. X
  810. X        (setf (method-function method)
  811. X              (symbol-function ',method-function-name)
  812. X        )
  813. X
  814. X        (add-method (discriminator-named ',method) method NIL)
  815. X      )
  816. X
  817. X    )
  818. X
  819. X   )
  820. X
  821. X  ) ;let*
  822. X
  823. X) ;build-pcl-method-def
  824. X
  825. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  826. X; Get/Set and Inherited Method Building Functions
  827. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  828. X
  829. X;;build-get-method-Build a gettable method
  830. X
  831. X(defun build-get-method (name methname var parents slots)
  832. X
  833. X  `(progn
  834. X    ,@(build-pcl-method-def 
  835. X      name 
  836. X      methname 
  837. X      '(.inner-self.) 
  838. X      `(%instance-ref .inner-self. ,(calculate-slot-index var parents slots))
  839. X    )
  840. X  )
  841. X
  842. X) ;end build-get-method
  843. X
  844. X;;build-set-method-Build a settable method
  845. X
  846. X(defun build-set-method (name methname var parents slots)
  847. X
  848. X  `(progn
  849. X    ,@(build-pcl-method-def 
  850. X      name 
  851. X      methname
  852. X      '(.inner-self. .new-value.)
  853. X      `(setf 
  854. X        (%instance-ref .inner-self. ,(calculate-slot-index var parents slots))
  855. X        .new-value.
  856. X       )
  857. X    )
  858. X  )
  859. X
  860. X) ;end build-set-method
  861. X
  862. X;;build-inherited-method-Return code for an inherited method.
  863. X
  864. X(defun build-inherited-method (name m p parents slots)
  865. X
  866. X  ;;Now generate code
  867. X
  868. X  `(progn
  869. X    ,@(build-pcl-method-def
  870. X        name
  871. X        m
  872. X        '(.inner-self. &rest .arg-list.)
  873. X        `(apply
  874. X        (symbol-function 
  875. X              ',(generate-method-function-symbol
  876. X               p m
  877. X                )
  878. X        )
  879. X            (%instance-ref
  880. X          .inner-self.
  881. X          ,(calculate-slot-index 
  882. X            p
  883. X            parents
  884. X                slots
  885. X              )
  886. X           )
  887. X       .arg-list.
  888. X
  889. X         )
  890. X      )
  891. X
  892. X  )
  893. X
  894. X) ;end build-inherited-method
  895. X
  896. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  897. X; Default Universal Methods
  898. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  899. X
  900. X;;define-universal-method-Macro to define universal methods. Note that
  901. X;;  DEFCOMMON-OBJECTS-METH could probably be used directly, but this
  902. X;;  tells what we're doing. We need a CommonObjects method here because
  903. X;;  we may need a symbol for CALL-METHOD
  904. X
  905. X(defmacro define-universal-method (name arglist &body body)
  906. X
  907. X   ;;Check for undefined type in body
  908. X
  909. X    (setf body 
  910. X      `(progn 
  911. X        (if (eq (class-name (class-of ,(first (first arglist)))) 
  912. X                $UNDEFINED-TYPE-NAME
  913. X            )
  914. X             (no-matching-method (discriminator-named ',name))
  915. X        )
  916. X        ,@body
  917. X      )
  918. X    )
  919. X
  920. X  (defcommon-objects-meth name arglist body)
  921. X
  922. X ) ;define-universal-method
  923. X
  924. X;;keyword-standin::init-Default :INIT method does nothing
  925. X
  926. X(define-universal-method keyword-standin::init 
  927. X  ((self common-objects-class) &rest keylist)
  928. X
  929. X
  930. X) ;keyword-standin::init
  931. X;;keyword-standin::initialize-Default :INITIALIZE initializes
  932. X;;  parents, then variables
  933. X
  934. X(define-universal-method keyword-standin::initialize 
  935. X  ((self common-objects-class) &rest keylist)
  936. X
  937. X    (let
  938. X      (
  939. X        (class (class-of self))
  940. X      )
  941. X
  942. X      (dolist (l (class-local-super-slot-names class))
  943. X
  944. X        ;;GET-SLOT is inserted in-line here
  945. X
  946. X        (apply 'keyword-standin::initialize 
  947. X          (%instance-ref self (slot-index class l))
  948. X          keylist
  949. X        )
  950. X      )
  951. X
  952. X      ;;Now initialize variables
  953. X
  954. X      (apply 'keyword-standin::initialize-variables self (car keylist))
  955. X      (apply 'keyword-standin::init self (car keylist))
  956. X
  957. X  ) ;let
  958. X
  959. X) ;keyword-standin::initialize
  960. X
  961. X;;print-instance-Print the instance
  962. X
  963. X(define-universal-method print-instance
  964. X  ((self common-objects-class) output-stream integer)
  965. X
  966. X  (if (or (not integer) 
  967. X          (not *print-level*) 
  968. X          (< integer *print-level*)
  969. X      )
  970. X
  971. X      (pcl::printing-random-thing (self output-stream)
  972. X    (format output-stream  "~A" (class-name (class-of self)))
  973. X      )
  974. X              
  975. X  )
  976. X
  977. X) ;print-instance
  978. X
  979. X;;keyword-standin::describe-Default :DESCRIBE method
  980. X
  981. X(define-universal-method keyword-standin::describe 
  982. X  ((self common-objects-class) &optional describe-inner-loop)
  983. X
  984. X  (let
  985. X    (
  986. X      (class (class-of self))
  987. X    )
  988. X
  989. X    (when (equal 
  990. X            (class-name (class-of class))
  991. X            'common-objects-class
  992. X           )
  993. X
  994. X      ;;Give name of this guy
  995. X
  996. X      (if (not describe-inner-loop)
  997. X        (format T 
  998. X            "This object of type ~A has variables:~%" 
  999. X            (class-name (class-of self))
  1000. X        )
  1001. X        (format T 
  1002. X                "For parent ~A:~%"
  1003. X            (class-name (class-of self))
  1004. X        )
  1005. X      ) ;if
  1006. X
  1007. X      ;;Now print instance variables
  1008. X
  1009. X      (dolist (slot (class-user-visible-slots class))
  1010. X        (format T "    ~A: ~S~%" slot (get-slot-using-class class self slot))
  1011. X      )
  1012. X
  1013. X      ;;Now print for parents
  1014. X
  1015. X      (dolist (lss (class-local-super-slot-names class))
  1016. X        (keyword-standin::describe (get-slot-using-class class self lss) T)
  1017. X      )
  1018. X
  1019. X    ) ;when
  1020. X
  1021. X  ) ;let
  1022. X
  1023. X) ;keyword-standin::describe
  1024. X
  1025. X;;keyword-standin::eql-Default :EQL predicate method
  1026. X
  1027. X(define-universal-method keyword-standin::eql 
  1028. X  ((self common-objects-class) .any.)
  1029. X
  1030. X      (eq self .any.)
  1031. X
  1032. X) ;keyword-standin::eql
  1033. X
  1034. X;;keyword-standin::equal-Default :EQUAL predicate method
  1035. X                                             
  1036. X(define-universal-method keyword-standin::equal 
  1037. X  ((self common-objects-class) .any.)
  1038. X
  1039. X   (keyword-standin::eql self .any.)
  1040. X
  1041. X) ;keyword-standin::equal
  1042. X
  1043. X;;keyword-standin::equalp-Default :EQUALP predicate method
  1044. X
  1045. X(define-universal-method keyword-standin::equalp 
  1046. X  ((self common-objects-class) .any.)
  1047. X
  1048. X  (keyword-standin::equal self .any.)
  1049. X
  1050. X) ;keyword-standin::equalp
  1051. X
  1052. X;;keyword-standin::typep-Default :TYPEP predicate method
  1053. X
  1054. X(define-universal-method keyword-standin::typep 
  1055. X  ((self common-objects-class) .any.)
  1056. X
  1057. X  (or (equal (class-name (class-of self)) .any.)
  1058. X      (eq .any. 'instance)
  1059. X      (eq .any. 't)
  1060. X  )
  1061. X
  1062. X) ;keyword-standin::typep
  1063. X
  1064. X;;keyword-standin::copy-Default :COPY method 
  1065. X
  1066. X(define-universal-method keyword-standin::copy 
  1067. X  ((self common-objects-class))
  1068. X
  1069. X      self
  1070. X
  1071. X) ;keyword-standin::copy
  1072. X
  1073. X;;keyword-standin::copy-instance-Default :COPY-INSTANCE method
  1074. X
  1075. X(define-universal-method keyword-standin::copy-instance 
  1076. X  ((self common-objects-class))
  1077. X
  1078. X  (let
  1079. X    (
  1080. X      (class (class-of self))
  1081. X      (inst NIL)
  1082. X    )
  1083. X
  1084. X    (when (equal 
  1085. X            (class-name (class-of class))
  1086. X            'common-objects-class
  1087. X           )
  1088. X
  1089. X      (setf inst (make-instance (class-name class)))
  1090. X
  1091. X      ;Copy state from inner-self to instance
  1092. X
  1093. X      (co::set-slot-values self inst class)
  1094. X
  1095. X      inst
  1096. X   ) ;when
  1097. X
  1098. X  ) ;let
  1099. X
  1100. X) ;keyword-standin::copy-instance
  1101. X
  1102. X;;keyword-standin::copy-state-Default :COPY-STATE method
  1103. X
  1104. X(define-universal-method keyword-standin::copy-state 
  1105. X  ((self common-objects-class))
  1106. X
  1107. X      self
  1108. X
  1109. X) ;keyword-standin::copy-state
  1110. X
  1111. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1112. X;  Support Methods and Functions for Universal Methods
  1113. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1114. X
  1115. X;;set-slot-values-Set the slot values in OBJECT to those in .INNER-SELF.
  1116. X
  1117. X(defmeth set-slot-values (.inner-self. object class)
  1118. X
  1119. X  ;;Set in this guy
  1120. X
  1121. X  (dolist (slot (class-user-visible-slots class))
  1122. X    (setf (get-slot object slot) (get-slot .inner-self. slot))
  1123. X  )
  1124. X
  1125. X  ;;Now set in parents
  1126. X
  1127. X  (dolist (lss (class-local-super-slot-names class))
  1128. X      (set-slot-values 
  1129. X    (get-slot .inner-self. lss) 
  1130. X    (get-slot object lss) 
  1131. X    (class-of (get-slot .inner-self. lss))
  1132. X      )
  1133. X  )
  1134. X
  1135. X) ;end set-slot-values
  1136. X
  1137. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1138. X;  Renaming and Undefining Types and Methods
  1139. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1140. X
  1141. X;;rename-type-Rename type1 to type2
  1142. X
  1143. X(defun rename-type (type1 type2)
  1144. X  (declare (type symbol type1 type2))
  1145. X
  1146. X  (let
  1147. X    (
  1148. X      (class (class-named type1 T))
  1149. X      (newclass (class-named type2 T))
  1150. X    )
  1151. X
  1152. X    ;;Signal an error for special cases
  1153. X
  1154. X    (when (or (null type2) (eq type2 't))
  1155. X      (error "RENAME-TYPE: New name cannot be NIL or T.~%")
  1156. X    )
  1157. X
  1158. X    ;;Signal an error when arguments aren't symbols
  1159. X
  1160. X    (when (or (not (symbolp type1)) (not (symbolp type2)))
  1161. X      (error "RENAME-TYPE: Arguments must be symbols.~%")
  1162. X    )
  1163. X
  1164. X    ;;Signal error if TYPE2 already exists
  1165. X
  1166. X    (when newclass
  1167. X      (error "RENAME-TYPE: Type ~S already exists.~%" type2)
  1168. X    )
  1169. X
  1170. X    ;;Signal an error if class isn't CommonObjects class
  1171. X
  1172. X    (when (not (eq (class-name (class-of class)) 'common-objects-class))
  1173. X      (error "RENAME-TYPE: Can't rename a built-in type or nonCommonObjects class ~S.~%" type1)
  1174. X    )
  1175. X
  1176. X    ;;Signal an error if the class is not defined
  1177. X
  1178. X    (if class
  1179. X      (progn
  1180. X    (rename-class class type2)
  1181. X        type2
  1182. X
  1183. X      ) ;progn
  1184. X      (error "RENAME-TYPE: The type ~S is not defined.~%" type1)
  1185. X    ) ;if
  1186. X
  1187. X  ) ;let
  1188. X
  1189. X) ;end rename-type
  1190. X
  1191. X;;undefine-type-Undefine type typename
  1192. X
  1193. X(defun undefine-type (typename)
  1194. X  (declare (type symbol typename))
  1195. X
  1196. X  ;;Check if typename is a symbol
  1197. X
  1198. X  (when (not (symbolp typename))
  1199. X    (error "UNDEFINE-TYPE: Argument must be a symbol.~%")
  1200. X  )
  1201. X
  1202. X  (let
  1203. X    (
  1204. X     (class (class-named typename T))
  1205. X    )
  1206. X
  1207. X    (if (and class (eq (class-name (class-of class)) 'common-objects-class))
  1208. X     (progn
  1209. X
  1210. X        ;;Undefine all the methods first
  1211. X
  1212. X        (undefine-methods class)
  1213. X
  1214. X        ;;Now set the class name
  1215. X
  1216. X        (setf (class-name class) $UNDEFINED-TYPE-NAME)
  1217. X    (setf (class-named typename) NIL)
  1218. X        T
  1219. X      ) ;progn
  1220. X
  1221. X      NIL
  1222. X
  1223. X    ) ;if
  1224. X
  1225. X  ) ;let
  1226. X
  1227. X) ;end undefine-type
  1228. X
  1229. X;;undefine-methods-Undefine all the methods on class
  1230. X
  1231. X(defun undefine-methods (class)
  1232. X
  1233. X  (dolist (meth (class-direct-methods class))
  1234. X
  1235. X    ;;Remove the method from the discriminator
  1236. X
  1237. X    (remove-method (method-discriminator meth) meth)
  1238. X    ;;Now unbind the symbol cell, so call-methods don't work
  1239. X
  1240. X    (fmakunbound (method-function-symbol meth))
  1241. X  )
  1242. X
  1243. X) ;undefine-methods
  1244. X
  1245. X;;undefine-method-Use PCL remove-method to get
  1246. X;;  rid of method.
  1247. X
  1248. X(defun undefine-method (typename operation)
  1249. X  (declare (type symbol typename operation))
  1250. X
  1251. X  ;;Check if the arguments are symbols
  1252. X
  1253. X  (when (not (symbolp typename)) 
  1254. X    (error "UNDEFINE-METHOD: Type name must be a symbol.~%")
  1255. X  )
  1256. X
  1257. X  ;;If the operation is not a symbol, just return.
  1258. X
  1259. X  (when (not (symbolp operation))
  1260. X    (return-from undefine-method NIL)
  1261. X  )
  1262. X
  1263. X  (let*
  1264. X    (
  1265. X
  1266. X      ;;The class object
  1267. X
  1268. X      (class (class-named typename))
  1269. X
  1270. X      ;;The operation
  1271. X
  1272. X      (opname (if (keywordp operation)
  1273. X                (keyword-standin operation)
  1274. X                operation
  1275. X              )
  1276. X      )
  1277. X
  1278. X      ;;The discriminator (if any)
  1279. X
  1280. X      (disc (discriminator-named opname))
  1281. X
  1282. X      ;;The method (if any)
  1283. X
  1284. X      (meth 
  1285. X        (if disc
  1286. X          (find-method disc (list typename) NIL T)
  1287. X        )
  1288. X      )
  1289. X
  1290. X    )
  1291. X
  1292. X
  1293. X    ;;Check if the class is a CommonObjects class
  1294. X
  1295. X    (when (not (eq (class-name (class-of class)) 'common-objects-class))
  1296. X      (error "UNDEFINE-TYPE: Tried to undefine ~S ~  
  1297. X              which is not a CommonObjects class.~%"
  1298. X              typename
  1299. X      )
  1300. X    )
  1301. X
  1302. X    ;;Check if the method is a universal method and there
  1303. X    ;; is no type specific method. Warn the user.
  1304. X
  1305. X    (when (and 
  1306. X            (null meth) 
  1307. X            (member operation *universal-methods* :test #'eq)
  1308. X          )
  1309. X      (warn
  1310. X        (format 
  1311. X          NIL
  1312. X          "UNDEFINE-TYPod NIL)
  1313. X  )
  1314. X
  1315. X  (let*
  1316. X    (
  1317. X
  1318. X      ;;The class ob% which cannot be undefined."
  1319. X      typename
  1320. X          operation
  1321. X        )
  1322. X      )
  1323. X      (return-from undefine-method NIL)
  1324. X    )            
  1325. X
  1326. X    ;;If a method was found, undefine it
  1327. X
  1328. X    (if (and meth disc)
  1329. X      (progn
  1330. X    (remove-method disc meth)
  1331. X        ;;Now unbind the symbol cell, so CALL-METHODs don't work
  1332. X
  1333. X    (fmakunbound (method-function-symbol meth))
  1334. X
  1335. X        ;;Remove the symbol from the package, so that future
  1336. X    ;;  attempts to create CALL-METHODs can't find it.
  1337. X    ;;  But hopefully, existing CALL-METHODs will still
  1338. X        ;;  work.
  1339. X
  1340. X        (unintern (method-function-symbol meth) 
  1341. X           (symbol-package (method-function-symbol meth))
  1342. X        )
  1343. X
  1344. X        T
  1345. X      ) ;progn
  1346. X
  1347. X      NIL
  1348. X
  1349. X    ) ;if
  1350. X
  1351. X  ) ;let
  1352. X
  1353. X) ;end undefine-method
  1354. X
  1355. X;;assignedp-Indicate whether or not an instance variable is
  1356. X;;  assigned
  1357. X
  1358. X(defmacro assignedp (var)
  1359. X
  1360. X  (declare (special co::*current-method-class-name*))
  1361. X
  1362. X  ;;Check for attempt to access outside of a method
  1363. X
  1364. X  (if (null (boundp 'co::*current-method-class-name*))
  1365. X    (error "DEFINE-METHOD: Attempt to use assignedp outside of a method.~%")
  1366. X  )
  1367. X
  1368. X  ;;Check for attempt to use on something other than an instance variable
  1369. X
  1370. X  (unless (has-slot-p (class-named *current-method-class-name*) var)
  1371. X    (error "DEFINE-METHOD: Argument ~S to assignedp ~
  1372. X           must be an instance variable name.~%" 
  1373. X           var
  1374. X     )
  1375. X  )
  1376. X
  1377. X  `(not (equal ,var ',$UNINITIALIZED-VARIABLE-FLAG))
  1378. X    
  1379. X) ;;end assignedp
  1380. X
  1381. X;;instancep-Return T if this thing is an instance and has a CommonObjects
  1382. X;;  class
  1383. X
  1384. X(defun instancep (thing)
  1385. X
  1386. X  ;;Check first if thing is NIL
  1387. X
  1388. X  (if (not thing)
  1389. X    NIL
  1390. X    (eq (class-name (class-of (class-of thing))) 'common-objects-class)
  1391. X  )
  1392. X
  1393. X
  1394. X) ;end instancep
  1395. X
  1396. X;;supports-operation-p-Return T if method operation METH is supported on type
  1397. X;;  of OBJ
  1398. X
  1399. X(defun supports-operation-p (obj meth)
  1400. X  (declare (special *universal-methods*))
  1401. X
  1402. X  (let
  1403. X    (
  1404. X      (class (if obj (class-of obj) obj))
  1405. X    )
  1406. X
  1407. X    ;;If not a CommonObjects class, then return NIL
  1408. X
  1409. X    (when (or (not class) 
  1410. X              (not (eq (class-name (class-of class)) 'common-objects-class))
  1411. X          )
  1412. X      (return-from supports-operation-p NIL)
  1413. X    )
  1414. X
  1415. X    ;;Check first if its a universal method
  1416. X
  1417. X    (if (member meth *universal-methods*)
  1418. X
  1419. X      T
  1420. X
  1421. X      ;;Otherwise, check in the class object if it's got them
  1422. X
  1423. X      (dolist (methobj (class-direct-methods class))
  1424. X
  1425. X        (when (eq (unkeyword-standin (method-name methobj)) meth)
  1426. X          (return-from supports-operation-p T)
  1427. X        )
  1428. X
  1429. X      ) ;dolist
  1430. X
  1431. X    ) ;if
  1432. X
  1433. X  ) ;let
  1434. X
  1435. X) ;end supports-operation-p
  1436. X
  1437. X;;Define the instance type
  1438. X
  1439. X(deftype instance ()
  1440. X  (list 'apply 'instancep)
  1441. X
  1442. X) ;end deftype
  1443. X
  1444. X
  1445. X
  1446. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1447. X;  Make-Instance
  1448. X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1449. X
  1450. X;;make-instance-Make an instance given the CommonObjects type name
  1451. X
  1452. X(defmeth make-instance ((class-name symbol) &rest keylist)
  1453. X
  1454. X    ;;Check if the key list and class are OK.
  1455. X
  1456. X    (if (null (listp keylist))
  1457. X      (error "Make-instance requires a list for the keyword list.~%")
  1458. X    )
  1459. X
  1460. X    (if (null (class-named class-name T))
  1461. X      (error "~S is not a defined type.~%" class-name)
  1462. X    )
  1463. X
  1464. X   (make-instance (class-named class-name) keylist)
  1465. X
  1466. X) ;end make-instance
  1467. X
  1468. X;;make-instance-Make an instance given the CommonObjects class object
  1469. X
  1470. X(defmeth make-instance ((class common-objects-class) &rest keylist)
  1471. X  (declare (special *outer-self*))
  1472. X  
  1473. X  (let*
  1474. X    (
  1475. X      (instance NIL)
  1476. X      (numslots (length (class-user-visible-slots class)))
  1477. X      (start-slots 
  1478. X    (+ $START-OF-PARENTS (length (class-local-supers class)))
  1479. X      )
  1480. X    )
  1481. X      (let 
  1482. X    (
  1483. X          (*outer-self* (and (boundp '*outer-self*) *outer-self*))
  1484. X        )
  1485. X        (declare (special *outer-self*))
  1486. X
  1487. X        (setf instance (%make-instance (class-of class)
  1488. X                       (+ 2 (class-instance-size class))
  1489. X                       )
  1490. X        )
  1491. X        (setf (%instance-ref instance $CLASS-OBJECT-INDEX) class
  1492. X          (%instance-ref instance $SELF-INDEX) (or *outer-self*
  1493. X                                    (setq *outer-self* instance)
  1494. X                            )
  1495. X        )
  1496. X
  1497. X        ;;Initialize the slots with the uninitialized flag
  1498. X
  1499. X        (dotimes (i numslots)
  1500. X          (setf 
  1501. X        (%instance-ref instance (+ i start-slots))
  1502. X            $UNINITIALIZED-VARIABLE-FLAG
  1503. X          )
  1504. X        )
  1505. X
  1506. X        ;;Now go through and make parent objects
  1507. X
  1508. X        (do 
  1509. X          (
  1510. X            (supers (class-local-supers class) (cdr supers))
  1511. X        (index $START-OF-PARENTS (1+ index))
  1512. X          )
  1513. X      ((null supers))
  1514. X      (setf (%instance-ref instance index)
  1515. X            (make-instance (car supers) (car keylist))
  1516. X          )
  1517. X        ) ;do
  1518. X
  1519. X    ) ;end let for dynamic binding
  1520. X
  1521. X    ;;Check initialization keywords and initialize, but only if
  1522. X    ;;  creating outer self object.
  1523. X
  1524. X    (when (not (boundp '*outer-self*))
  1525. X
  1526. X      ;;If keyword check needed, then check keyword list
  1527. X
  1528. X      (if (class-init-keywords-check class)
  1529. X        (check-init-keywords class keylist)
  1530. X      )
  1531. X      ;;Now initialize, if doing outer self.
  1532. X
  1533. X      (keyword-standin::initialize instance (car keylist))
  1534. X
  1535. X    ) ;when
  1536. X
  1537. X    instance
  1538. X
  1539. X  ) ;end let for lexical binding
  1540. X
  1541. X) ;end make-instance
  1542. X
  1543. END_OF_FILE
  1544. if test 36944 -ne `wc -c <'co-dtype.l'`; then
  1545.     echo shar: \"'co-dtype.l'\" unpacked with wrong size!
  1546. fi
  1547. # end of 'co-dtype.l'
  1548. fi
  1549. echo shar: End of archive 11 \(of 13\).
  1550. cp /dev/null ark11isdone
  1551. MISSING=""
  1552. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1553.     if test ! -f ark${I}isdone ; then
  1554.     MISSING="${MISSING} ${I}"
  1555.     fi
  1556. done
  1557. if test "${MISSING}" = "" ; then
  1558.     echo You have unpacked all 13 archives.
  1559.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1560. else
  1561.     echo You still need to unpack the following archives:
  1562.     echo "        " ${MISSING}
  1563. fi
  1564. ##  End of shell archive.
  1565. exit 0
  1566. -- 
  1567.  
  1568. Rich $alz            "Anger is an energy"
  1569. Cronus Project, BBN Labs    rsalz@bbn.com
  1570. Moderator, comp.sources.unix    sources@uunet.uu.net
  1571.